package gui;

import gui.transparent.TransparentPasswordField;
import gui.transparent.TransparentTextField;

import java.awt.AWTException;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import javax.swing.BorderFactory;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JSeparator;
import javax.swing.JTabbedPane;
import javax.swing.JToggleButton;
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileFilter;

import org.jdesktop.swingx.JXButton;
import org.jdesktop.swingx.JXFrame;
import org.jdesktop.swingx.JXLabel;
import org.jdesktop.swingx.JXPanel;

import si.DateTime;

import com.db4o.ObjectServer;
import com.db4o.cs.Db4oClientServer;

import common.IniDB;
import common.IniItem;

public class Server extends JXFrame
{
    private static final String BACKUP_SUFIX = ".bcp";
    private final SystemTray tray = SystemTray.getSystemTray();
    PopupMenu popup = new PopupMenu();
    private final TrayIcon trayIcon = new TrayIcon(Global.ICON_TRAYICO
	    .getImage(), "DB4O Server", popup);

    private ObjectServer server = null;
    private String databaseFileName = null;
    private int port = 0;
    private String user = null;
    private String pass = null;
    private boolean stop = true;
    private boolean timerOn = false;
    private int timer = 0;

    private JTabbedPane tabPaneMain = new JTabbedPane(JTabbedPane.TOP);

    private JXPanel pnlServer;
    private JXPanel pnlServerSub;
    private JXLabel lblServer;
    private JXLabel lblDBName;
    private JXLabel lblServerInfo;
    private TransparentTextField txfDatabase;
    private JXLabel lblPort;
    private TransparentTextField txfPort;

    private JXPanel pnlUser;
    private JXPanel pnlUserSub;
    private JXLabel lblUser;
    private JXLabel lblUserName;
    private JXLabel lblUserInfo;

    private TransparentTextField txfUsername;
    private JXLabel lblPassword;
    private TransparentPasswordField pwfPassword;
    private JToggleButton btnEchoChar;

    private JXPanel pnlService;
    private JXPanel pnlServiceSub;
    private JXLabel lblService;
    private JXLabel lblServiceInfo;
    private JXLabel lblServiceStatus;
    private JToggleButton btnService;

    private JXPanel pnlBackup;
    private JXPanel pnlBackupSub;
    private JXLabel lblBackup;
    private JXLabel lblBackupInfo;
    private JXButton btnBackup;
    private JCheckBox cbxBackupTimer;
    private JXLabel lblTimerClock;
    private JXLabel lblBackupTimer;
    private JComboBox comboxTimer;
    private JXLabel lblBackupDir;
    private TransparentTextField txfBackupDir;

    private JXPanel pnlRestore;
    private JXPanel pnlRestoreSub;
    private JXLabel lblRestore;
    private JXLabel lblRestoreInfo;
    private JXButton btnRestore;

    private String[] serviceStatus = { "The server is not activ!",
	    "The Server is activ!" };
    private String[] time = { "Minute", "Hour", "1/2 Day", "Day", "Week" };

    public Server()
    {
	super("DB4O-Server");
	initComponents();
	initPanels();
	initListener();
	initTexts();
	initToolTipps();
	initSizes();
	readIniFile();
	setupFrame();
    }

    private void initComponents()
    {
	// Server
	pnlServer = new JXPanel(new GridBagLayout());
	pnlServerSub = new JXPanel(new GridBagLayout());
	lblServer = new JXLabel("Server", Global.ICON_16_COMPUTER, JXLabel.LEFT);
	lblDBName = new JXLabel("Database:", Global.ICON_16_DATABASE,
		JXLabel.LEFT);
	lblServerInfo = new JXLabel(Global.ICON_32_INFO);
	txfDatabase = new TransparentTextField(30);
	lblPort = new JXLabel("Port:", Global.ICON_16_PORT, JXLabel.LEFT);
	txfPort = new TransparentTextField(4);

	// User
	pnlUser = new JXPanel(new GridBagLayout());
	pnlUserSub = new JXPanel(new GridBagLayout());
	lblUser = new JXLabel("User", Global.ICON_16_USERS, JXLabel.LEFT);
	lblUserName = new JXLabel("User:", Global.ICON_16_USER, JXLabel.LEFT);
	lblUserInfo = new JXLabel(Global.ICON_32_INFO);
	txfUsername = new TransparentTextField(10);
	lblPassword = new JXLabel("Password:", Global.ICON_16_LOCK,
		JXLabel.LEFT);
	pwfPassword = new TransparentPasswordField();
	btnEchoChar = new JToggleButton("Show");

	// Service
	pnlService = new JXPanel(new GridBagLayout());
	pnlServiceSub = new JXPanel(new GridBagLayout());
	lblService = new JXLabel("Service", Global.ICON_16_PROCESS,
		JXLabel.LEFT);
	lblServiceStatus = new JXLabel(serviceStatus[0],
		Global.ICON_16_PROCESS_REMOVE, 0);
	lblServiceInfo = new JXLabel(Global.ICON_32_INFO);
	btnService = new JToggleButton("Start", Global.ICON_16_PROCESS_ACCEPT);
	pnlBackup = new JXPanel(new GridBagLayout());

	// Backup
	pnlBackup = new JXPanel(new GridBagLayout());
	pnlBackupSub = new JXPanel(new GridBagLayout());
	lblBackup = new JXLabel("Backup", Global.ICON_16_DATABASE_DOWN,
		JXLabel.LEFT);
	lblBackupInfo = new JXLabel(Global.ICON_32_INFO);
	btnBackup = new JXButton("Backup", Global.ICON_16_DOWN);
	cbxBackupTimer = new JCheckBox("Autobackup");
	lblBackupTimer = new JXLabel("Backup every", Global.ICON_16_CLOCK,
		JXLabel.LEFT);
	comboxTimer = new JComboBox(time);
	lblBackupDir = new JXLabel("Backup folder", Global.ICON_16_FOLDER,
		JXLabel.LEFT);
	txfBackupDir = new TransparentTextField();
	lblTimerClock = new JXLabel();

	// Resore
	pnlRestore = new JXPanel(new GridBagLayout());
	pnlRestoreSub = new JXPanel(new GridBagLayout());
	lblRestore = new JXLabel("Restore", Global.ICON_16_DATABASE_UP,
		JXLabel.LEFT);
	lblRestoreInfo = new JXLabel(Global.ICON_32_INFO);
	btnRestore = new JXButton("Restore", Global.ICON_16_REPEAT);

	setBackupEnable(false);
    }

    private void initPanels()
    {
	/** User **/
	{
	    // Info
	    Global.addCom(pnlUser, lblUserInfo, 0, 0, 1, 1, 0, 0);
	    // Separator
	    Global.addCom(pnlUser, new JSeparator(), 0, 1, 1, 1, 0, 0);
	    // Username
	    Global.addCom(pnlUserSub, lblUserName, 0, 0, 1, 1, 0, 0);
	    Global.addCom(pnlUserSub, txfUsername, 1, 0, 1, 1, 0, 0);
	    // Password
	    Global.addCom(pnlUserSub, lblPassword, 0, 1, 1, 1, 0, 0);
	    Global.addCom(pnlUserSub, pwfPassword, 1, 1, 1, 1, 0, 0);
	    Global.addCom(pnlUserSub, btnEchoChar, 2, 1, 1, 1, 0, 0);
	    // panelSub
	    Global.addCom(pnlUser, pnlUserSub, 0, 2, 1, 1, 0, 0);
	    // leer
	    Global.addCom(pnlUser, new JLabel(), 0, 3, 2, 1, 1, 1);
	    // Border
	    pnlUserSub.setBorder(BorderFactory.createTitledBorder(" "));
	    // add to tab
	    tabPaneMain.addTab("User", pnlUser);
	    // set tab label
	    tabPaneMain.setTabComponentAt(0, lblUser);
	}

	/** Server **/
	{
	    // Info
	    Global.addCom(pnlServer, lblServerInfo, 0, 0, 1, 1, 0, 0);
	    // Separator
	    Global.addCom(pnlServer, new JSeparator(), 0, 1, 1, 1, 0, 0);

	    // Datenbank
	    Global.addCom(pnlServerSub, lblDBName, 0, 0, 1, 1, 0, 0);
	    Global.addCom(pnlServerSub, txfDatabase, 1, 0, 2, 1, 0, 0);
	    // Port
	    Global.addCom(pnlServerSub, lblPort, 0, 1, 1, 1, 0, 0);
	    Global.addCom(pnlServerSub, txfPort, 1, 1, 1, 1, 0, 0);
	    // panelSub
	    Global.addCom(pnlServer, pnlServerSub, 0, 2, 1, 1, 0, 0);
	    // leer
	    Global.addCom(pnlServer, new JLabel(), 0, 3, 2, 1, 1, 1);
	    // Border
	    pnlServerSub.setBorder(BorderFactory.createTitledBorder(" "));
	    // add to tab
	    tabPaneMain.addTab("Server", pnlServer);
	    // set tab label
	    tabPaneMain.setTabComponentAt(1, lblServer);
	}

	/** Service **/
	{
	    // Info
	    Global.addCom(pnlService, lblServiceInfo, 0, 0, 1, 1, 0, 0);
	    // Separator
	    Global.addCom(pnlService, new JSeparator(), 0, 1, 1, 1, 0, 0);
	    // Status
	    Global.addCom(pnlServiceSub, lblServiceStatus, 0, 0, 1, 1, 0, 0);
	    // leer
	    Global.addCom(pnlServiceSub, new JLabel(""), 1, 0, 1, 1, 1, 0);
	    // Button Start
	    Global.addCom(pnlServiceSub, btnService, 2, 0, 1, 1, 0, 0);
	    // lblServiceStatus
	    Global.addCom(pnlService, pnlServiceSub, 0, 1, 1, 1, 0, 0);
	    // leer
	    Global.addCom(pnlService, new JLabel(""), 0, 3, 2, 1, 1, 1);
	    // Border
	    pnlServiceSub.setBorder(BorderFactory.createTitledBorder(" "));
	    // add to tab
	    tabPaneMain.addTab("Service", pnlService);
	    // set tab label
	    tabPaneMain.setTabComponentAt(2, lblService);
	}

	/** Backup **/
	{
	    // Info
	    Global.addCom(pnlBackup, lblBackupInfo, 0, 0, 1, 1, 0, 0);
	    // Separator
	    Global.addCom(pnlBackup, new JSeparator(), 0, 1, 1, 1, 0, 0);
	    // Button Backup
	    Global.addCom(pnlBackupSub, btnBackup, 0, 0, 1, 1, 0, 0);
	    // Button Backup
	    Global.addCom(pnlBackupSub, new JLabel(" "), 2, 0, 2, 1, 1, 0);
	    // Separator
	    Global.addCom(pnlBackupSub, new JSeparator(), 0, 1, 4, 1, 1, 0);
	    // Checkbox Timer
	    Global.addCom(pnlBackupSub, cbxBackupTimer, 0, 2, 1, 1, 0, 0);
	    Global.addCom(pnlBackupSub, lblTimerClock, 1, 2, 2, 1, 0, 0);
	    // Timer
	    Global.addCom(pnlBackupSub, lblBackupTimer, 0, 3, 1, 1, 0, 0);
	    // Timer Combobox
	    Global.addCom(pnlBackupSub, comboxTimer, 1, 3, 1, 1, 0, 0);
	    // Folder Label
	    Global.addCom(pnlBackupSub, lblBackupDir, 0, 4, 1, 1, 0, 0);
	    // Folder TXField
	    Global.addCom(pnlBackupSub, txfBackupDir, 1, 4, 3, 1, 0, 0);
	    // leer
	    // Global.addCom(pnlBackupSub, new JLabel(""), 1, 0, 1, 1, 1, 0);
	    // Global.addCom(pnlBackupSub, btnService, 2, 0, 1, 1, 0, 0);
	    // lblServiceStatus
	    Global.addCom(pnlBackup, pnlBackupSub, 0, 1, 1, 1, 0, 0);
	    // leer
	    Global.addCom(pnlBackup, new JLabel(""), 0, 3, 2, 1, 1, 1);
	    // Border
	    pnlBackupSub.setBorder(BorderFactory.createTitledBorder(" "));
	    // add to tab
	    tabPaneMain.addTab("Backup", pnlBackup);
	    // set tab label
	    tabPaneMain.setTabComponentAt(3, lblBackup);
	}

	/** **/
	{
	    // Info
	    Global.addCom(pnlRestore, lblRestoreInfo, 0, 0, 1, 1, 0, 0);
	    // Separator
	    Global.addCom(pnlRestore, new JSeparator(), 0, 1, 1, 1, 0, 0);
	    // Status
	    Global.addCom(pnlRestoreSub, btnRestore, 0, 0, 1, 1, 0, 0);
	    // leer
	    // Global.addCom(pnlServiceSub, new JLabel(""), 1, 0, 1, 1, 1, 0);
	    // Button Start
	    // Global.addCom(pnlServiceSub, btnService, 2, 0, 1, 1, 0, 0);
	    // lblServiceStatus
	    Global.addCom(pnlRestore, pnlRestoreSub, 0, 1, 1, 1, 0, 0);
	    // leer
	    Global.addCom(pnlRestore, new JLabel(""), 0, 3, 2, 1, 1, 1);
	    // Border
	    pnlRestoreSub.setBorder(BorderFactory.createTitledBorder(" "));
	    // add to tab
	    tabPaneMain.addTab("Restore", pnlRestore);
	    // set tab label
	    tabPaneMain.setTabComponentAt(4, lblRestore);
	}

	tabPaneMain.setFocusable(false);
    }

    private void initListener()
    {
	txfDatabase.addMouseListener(new MouseAdapter() {
	    @Override
	    public void mouseClicked(MouseEvent me)
	    {
		super.mouseClicked(me);
		if (me.getClickCount() > 1)
		    showDBFileChooser();
	    }
	});

	btnEchoChar.addActionListener(new ActionListener() {
	    @Override
	    public void actionPerformed(ActionEvent arg0)
	    {
		if (btnEchoChar.isSelected()) {
		    btnEchoChar.setText("Hide");
		    pwfPassword.setEchoChar(false);
		} else {
		    btnEchoChar.setText("Show");
		    pwfPassword.setEchoChar(true);
		}
	    }
	});

	txfPort.addMouseListener(new MouseAdapter() {
	    @Override
	    public void mouseClicked(MouseEvent me)
	    {
		super.mouseClicked(me);
		if (me.getClickCount() > 1)
		    txfPort.setText("8732");
	    }
	});

	txfPort.addKeyListener(new KeyAdapter() {
	    @Override
	    public void keyTyped(KeyEvent ke)
	    {
		if (!Character.isDigit(ke.getKeyChar())
			|| txfPort.getText().length() >= 5)
		    ke.consume();

	    }
	});

	btnService.addActionListener(new ActionListener() {
	    @Override
	    public void actionPerformed(ActionEvent arg0)
	    {
		if (btnService.isSelected() && initSettings()) {
		    btnService.setIcon(Global.ICON_16_PROCESS_REMOVE);
		    btnService.setText("Stop");
		    lblServiceStatus.setIcon(Global.ICON_16_PROCESS_ACCEPT);
		    lblServiceStatus.setText(serviceStatus[1]);
		    stop = false;
		    new Thread(startServer).start();
		} else {
		    btnService.setSelected(false);
		    try {
			Thread.sleep(500);
		    } catch (Exception e) {
		    }
		    btnService.setIcon(Global.ICON_16_PROCESS_ACCEPT);
		    btnService.setText("Start");
		    lblServiceStatus.setIcon(Global.ICON_16_PROCESS_REMOVE);
		    lblServiceStatus.setText(serviceStatus[0]);
		    stop = true;
		    tray.remove(trayIcon);
		}
	    }
	});

	btnBackup.addActionListener(new ActionListener() {

	    @Override
	    public void actionPerformed(ActionEvent arg0)
	    {
		showBackupFileChooser();
	    }
	});

	btnRestore.addActionListener(new ActionListener() {

	    @Override
	    public void actionPerformed(ActionEvent arg0)
	    {
		showRestoreFileChooser();
	    }
	});

	cbxBackupTimer.addActionListener(new ActionListener() {

	    @Override
	    public void actionPerformed(ActionEvent ae)
	    {
		setBackupEnable(!cbxBackupTimer.isSelected());
		cbxBackupTimer.setEnabled(true);
		btnBackup.setEnabled(true);
		if (cbxBackupTimer.isSelected()) {
		    btnRestore.setEnabled(false);
		    int index = comboxTimer.getSelectedIndex();
		    if (index == 0)
			timer = 60; // minute
		    else if (index == 1)
			timer = 60 * 60; // hour
		    else if (index == 2)
			timer = 60 * 60 * 12; // 1/2 day
		    else if (index == 4)
			timer = 60 * 60 * 24 * 7; // week
		    else
			timer = 60 * 60 * 24; // day

		    new Thread(startTimer).start();
		    return;
		} else {
		    timerOn = false;
		    lblTimerClock.setText("");
		}
	    }
	});
    }

    private void initToolTipps()
    {
	txfDatabase.setToolTipText("Dubble click for open File Chooser.");
	txfPort.setToolTipText("From 0 to 65535. Standard: 8732");
    }

    private void initTexts()
    {

	// Port
	txfPort.setText("8732");
	// ServerInfo
	String info = "<html>In this tab you can set the path where the database file will be stored<br>"
		+ "or you can choose an existing databse file to use it.<br>"
		+ "Aslo you can set the port which will be opened for the clients to cennect to this server.</html>";
	lblServerInfo.setText(info);
	lblServerInfo.setVerticalTextPosition(JLabel.TOP);
	// UserInfo
	info = "<html>In this tab you can set user and password.<br>"
		+ "<b>With this values the clients can connect to this server.</html>";
	lblUserInfo.setText(info);
	lblUserInfo.setVerticalTextPosition(JLabel.TOP);
	// ServiceInfo
	info = "<html>Here you can start or stop the server.<br>"
		+ "<b>Remember if you stop the server all clients will be disconnected.";
	lblServiceInfo.setText(info);
	lblServiceInfo.setVerticalTextPosition(JLabel.TOP);
	// Username
	txfUsername.setText("supervisor");
	// Password
	pwfPassword.setText("Admin1!");
	// BackupInfo
	info = "<html>In this tab you can backup your database.<br>"
		+ "You can also set backup timer which will backup your database automaticly.<br>"
		+ "<b>Imagine, the Service must be running before it is able to backup a database!</html>";
	lblBackupInfo.setText(info);
	lblBackupInfo.setVerticalTextPosition(JLabel.TOP);
	// Restore
	info = "<html>Before you can restore a database, the service must be stopped!<br>"
		+ "After the restoring you must change the database to use the resored database.<br>"
		+ "<b>Imagine, the database backup file will be inviolate and can be used several times!</html>";
	lblRestoreInfo.setText(info);
	lblRestoreInfo.setVerticalTextPosition(JLabel.TOP);
    }

    private Runnable startServer = new Runnable() {
	@Override
	public void run()
	{
	    try {
		server = Db4oClientServer.openServer(databaseFileName, port);
		// server = Db4o.openServer(databaseFileName, port);
		server.grantAccess(user, pass);
		new Thread(service).start();
		boolean a = true;
		setBackupEnable(true);
		while (!stop) {
		    lblServiceStatus.setIcon(a ? Global.ICON_16_PROCESS_ACCEPT
			    : Global.ICON_16_PROCESS);
		    a = !a;
		    try {
			Thread.sleep(500);
		    } catch (InterruptedException e) {
		    }
		}
		setBackupEnable(false);
		if (cbxBackupTimer.isSelected()) {
		    cbxBackupTimer.setSelected(false);
		    timerOn = false;
		    lblTimerClock.setText("");
		}
		server.close();
		server = null;
	    } catch (Exception e) {
		btnService.doClick();
		btnService.setEnabled(false);
	    }
	}
    };

    private Runnable startTimer = new Runnable() {
	@Override
	public void run()
	{
	    timerOn = true;
	    while (timerOn) {
		int stopper = timer;

		while (stopper > 0 && timerOn) {
		    int sec = stopper % 60;
		    int min = (stopper / 60) % (60);
		    int hour = (stopper / 60 / 60) % (24);
		    int day = stopper / (60 * 60 * 24);
		    String text = "";
		    if (day > 0)
			text = day + " days + ";
		    if (hour == 0)
			text += "00:";
		    else if (hour < 10)
			text += "0" + hour + ":";
		    else
			text += hour + ":";

		    if (min == 0)
			text += "00:";
		    else if (min < 10)
			text += "0" + min + ":";
		    else
			text += min + ":";

		    if (sec == 0)
			text += "00";
		    else if (min < 10)
			text += "0" + sec + "";
		    else
			text += sec + "";

		    lblTimerClock.setText("Next backup: " + text);
		    stopper--;
		    try {
			Thread.sleep(1000);
		    } catch (Exception e) {
		    }
		}
		if (!timerOn)
		    break;
		try {
		    File dir = new File(txfBackupDir.getText());
		    dir.mkdir();
		    String filename = DateTime.getTimeStamp() + BACKUP_SUFIX;// new
									     // ADateTime().getDateTime()
									     // +
									     // BACKUP_SUFIX;

		    System.out.println(filename);
		    if (dir.exists()) {
			server.ext().backup(
				txfBackupDir.getText() + File.separator
					+ filename);
		    } else
			server.ext().backup(filename);
		} catch (IOException e) {
		}
	    }
	}
    };

    private Runnable service = new Runnable() {
	public void run()
	{
	    if (SystemTray.isSupported()) {
		trayIcon.addMouseListener(new MouseAdapter() {
		    @Override
		    public void mouseClicked(MouseEvent me)
		    {
			super.mouseClicked(me);
			if (me.getClickCount() == 2) {
			    setVisible(true);
			    // tray.remove(trayIcon);
			}
		    }
		});

		try {
		    tray.add(trayIcon);
		} catch (AWTException e) {
		    System.err.println("Can't add to tray");
		}
	    } else {
		System.err.println("Tray unavailable");
	    }
	}
    };

    private void initSizes()
    {
	btnEchoChar.setPreferredSize(new Dimension(60, 25));
    }

    private void readIniFile()
    {
	// user
	user = IniDB.getValueString(IniDB.CONFIG_INI, Global.SECTION_CAPTURE, Global.KEY_USER, "supervisor");
	txfUsername.setText(user);
	// pass
	pass = IniDB.getValueString(IniDB.CONFIG_INI, Global.SECTION_CAPTURE, Global.KEY_PASS, "Admin1!");
	pwfPassword.setText(pass);
	// database
	String db = new JFileChooser(".").getCurrentDirectory()
		.getAbsolutePath()
		+ File.separator + "db.yap";
	db = db.replace(File.separator + File.separator, File.separator);
	databaseFileName = IniDB.getValueString(IniDB.CONFIG_INI, Global.SECTION_CAPTURE, Global.KEY_DB, db);
	txfDatabase.setText(databaseFileName);
	// port
	port = IniDB.getValueInt(IniDB.CONFIG_INI, Global.SECTION_CAPTURE, Global.KEY_PORT, 8732);
	txfPort.setText(port + "");
	// Backup
	String backupFolder = new JFileChooser(".").getCurrentDirectory().getAbsolutePath() + File.separator + "Backup";
	backupFolder = backupFolder.replace(File.separator + File.separator, File.separator);
	backupFolder = IniDB.getValueString(IniDB.CONFIG_INI, Global.SECTION_CAPTURE, Global.KEY_BACKUP, backupFolder);
	txfBackupDir.setText(backupFolder);
    }

    private void setupFrame()
    {

	getContentPane().add(tabPaneMain);
	setDefaultCloseOperation(JXFrame.DISPOSE_ON_CLOSE);
	pack();
	setMinimumSize(getSize());
	Global.centred(this);
	setVisible(true);
    }

    private void showDBFileChooser()
    {
	FileFilter fileFilter = new FileFilter() {
	    @Override
	    public String getDescription()
	    {
		return "*.yap";
	    }

	    @Override
	    public boolean accept(File file)
	    {
		return file.toString().toLowerCase().endsWith(".yap");
	    }
	};
	JFileChooser fileChooser = new JFileChooser(".");
	fileChooser.setFileFilter(fileFilter);
	fileChooser.showDialog(this, null);
	if (fileChooser.getSelectedFile() != null)
	    txfDatabase
		    .setText(fileChooser.getSelectedFile().getAbsolutePath());
    }

    private void showBackupFileChooser()
    {
	FileFilter fileFilter = new FileFilter() {
	    @Override
	    public String getDescription()
	    {
		return "*" + BACKUP_SUFIX;
	    }

	    @Override
	    public boolean accept(File file)
	    {
		return file.getAbsoluteFile().toString().toLowerCase()
			.endsWith(BACKUP_SUFIX)
			|| file.isDirectory();
	    }
	};
	JFileChooser f = new JFileChooser(".");
	f.setFileFilter(fileFilter);
	// f.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
	f.showSaveDialog(this);
	if (f.getSelectedFile() == null)
	    return;
	String filename = f.getSelectedFile().getAbsolutePath().toLowerCase();
	if (!filename.endsWith(BACKUP_SUFIX))
	    filename += BACKUP_SUFIX;
	try {
	    server.ext().backup(filename);
	    JOptionPane.showMessageDialog(this, "Backup was successful!",
		    "Backup finished!", JOptionPane.OK_OPTION,
		    Global.ICON_32_INFO);
	} catch (IOException e) {
	}
    }

    private void showRestoreFileChooser()
    {
	FileFilter fileFilter = new FileFilter() {
	    @Override
	    public String getDescription()
	    {
		return "*" + BACKUP_SUFIX;
	    }

	    @Override
	    public boolean accept(File file)
	    {
		return file.getAbsoluteFile().toString().toLowerCase()
			.endsWith(BACKUP_SUFIX)
			|| file.isDirectory();
	    }
	};
	JFileChooser f = new JFileChooser(".");
	f.setFileFilter(fileFilter);
	// f.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
	f.showOpenDialog(this);
	if (f.getSelectedFile() == null)
	    return;
	String filename = f.getSelectedFile().getAbsolutePath();
	try {
	    File inputFile = new File(filename);
	    File outputFile = new File(filename.replace(BACKUP_SUFIX, ".yap"));

	    FileReader in = new FileReader(inputFile);
	    FileWriter out = new FileWriter(outputFile);
	    int c;

	    while ((c = in.read()) != -1)
		out.write(c);

	    in.close();
	    out.close();

	    JOptionPane.showMessageDialog(this,
		    "The database was restored to \"" + outputFile + "\"!",
		    "Restore finished!", JOptionPane.OK_OPTION,
		    Global.ICON_32_INFO);
	    txfDatabase.setText(filename);
	} catch (IOException e) {
	    JOptionPane.showMessageDialog(this,
		    "The restoring was not successful!", "Restore finished!",
		    JOptionPane.OK_OPTION, Global.ICON_48_WARNING);
	}
    }

    private boolean initSettings()
    {
	try {
	    user = txfUsername.getText().trim();

	    pass = new String(pwfPassword.getPassword()).trim();

	    databaseFileName = txfDatabase.getText().trim();

	    port = Integer.parseInt(txfPort.getText().trim());
	    if (user.isEmpty() || pass.isEmpty() || databaseFileName.isEmpty()
		    || port < 0 || port > 65535)
		return false;

	    IniDB.saveIniItem(IniDB.CONFIG_INI, new IniItem(
		    Global.SECTION_CAPTURE, Global.KEY_USER, user));
	    IniDB.saveIniItem(IniDB.CONFIG_INI, new IniItem(
		    Global.SECTION_CAPTURE, Global.KEY_PASS, pass));
	    IniDB.saveIniItem(IniDB.CONFIG_INI, new IniItem(
		    Global.SECTION_CAPTURE, Global.KEY_DB, databaseFileName));
	    IniDB.saveIniItem(IniDB.CONFIG_INI, new IniItem(
		    Global.SECTION_CAPTURE, Global.KEY_PORT, port));
	    return true;
	} catch (Exception e) {
	    return false;
	}
    }

    private void setBackupEnable(boolean enable)
    {
	btnBackup.setEnabled(enable);
	cbxBackupTimer.setEnabled(enable);
	txfBackupDir.setEnabled(enable);
	comboxTimer.setEnabled(enable);
	lblBackupTimer.setEnabled(enable);
	lblBackupDir.setEnabled(enable);
	btnRestore.setEnabled(!enable);
    }

    public static void main(String[] args)
    {
	Global.setLookAndFeel(Global.LAF_NIMBUS);
	SwingUtilities.invokeLater(new Runnable() {
	    @Override
	    public void run()
	    {
		new Server();
	    }
	});
    }

}
